package com.numone.testble.ble;

import android.app.Application;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.numone.testble.App;

import java.util.ArrayList;
import java.util.List;

public class BleScanPresenter {

    private List<BleEntity> bleList = null;

    private ScanHandler scanHandler;
    public final static int H_DISCOVERY_FINISHED = 0x01;
    public final static int H_DISCOVERY_FOUND = 0x02;
    public final static int H_DISCOVERY_TIME_OUT = 0x03;

    public BleScanPresenter(){
        scanHandler = new ScanHandler(Looper.getMainLooper());
    }

    public synchronized List<BleEntity> getBleList() {
//        if(null != bleList){
//            Gson gson = new Gson();
//            Logger.d(gson.toJson(bleList));
//        }
        return bleList;
    }

    private ScanBroadcastReceiver scanBroadcastReceiver;
    /**
     * 使用新api扫描
     * 注册蓝牙扫描监听
     */
    public synchronized void registerScanBroadcast() {
        Application application = App.getApp();
        //注册蓝牙扫描状态广播接收者
        if (scanBroadcastReceiver == null && application != null) {
            scanBroadcastReceiver = new ScanBroadcastReceiver();
            IntentFilter filter = new IntentFilter();
            //开始扫描
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            //扫描结束
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            //扫描中，返回结果
            filter.addAction(BluetoothDevice.ACTION_FOUND);
            //扫描模式改变
            filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
//            filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//            filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
            application.registerReceiver(scanBroadcastReceiver, filter);
        }
    }

    public void unregisterScanBroadcast(){
        try{
            if(null != App.getApp() && null != scanBroadcastReceiver){
                App.getApp().unregisterReceiver(scanBroadcastReceiver);
                scanBroadcastReceiver = null;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //监听扫描广播
    private class ScanBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("BluetoothScan","intent="+intent.toString());
            String action = intent.getAction();
            if (action != null) {
                //获取蓝牙设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                switch (action) {
                    case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED:
                        Log.d("BluetoothScan","扫描模式改变");
                        break;
                    case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                        Log.d("BluetoothScan","扫描开始");
                        break;
                    case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                        Log.d("BluetoothScan","扫描结束");
                        onScanFinished();
                        break;
                    case BluetoothDevice.ACTION_FOUND:
                        scanHandler.removeMessages(H_DISCOVERY_TIME_OUT);
                        if (device != null && null != device.getName()) {
                            int rssi = -120;
                            Bundle extras = intent.getExtras();
                            String lv = "";
                            if (extras != null) {
                                //信号强度
                                rssi = extras.getShort(BluetoothDevice.EXTRA_RSSI);
                            }
                            StringBuffer buffer = new StringBuffer();
                            buffer.append("rssi=" + rssi);
                            buffer.append("\nname=" + device.getName());
                            buffer.append("\ngetBondState=" + device.getBondState());
                            buffer.append("\naddress=" + device.getAddress());
                            buffer.append("\ngetType=" + device.getType());
                            buffer.append("\ngetBluetoothClass=" + device.getBluetoothClass());
                            buffer.append("\ngetUuids=" + device.getUuids());
                            buffer.append("\nlv=" + lv);
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                                buffer.append("\ngetAlias=" + device.getAlias());
                            }
                            Log.d("BluetoothScan", buffer.toString());
                            if(null == bleList){
                                bleList = new ArrayList<>();
                            }
                            BleEntity entity = new BleEntity();
                            int size = bleList.size();
                            entity.setId(size>0?bleList.get(size-1).getId()+1:0);
                            entity.setMac(device.getAddress());
                            entity.setName(device.getName());
                            entity.setRssi(rssi);
                            bleList.add(entity);
                            Message message = Message.obtain();
                            message.what = H_DISCOVERY_FOUND;
                            message.obj = device;
                            message.arg1 = rssi;
                            scanHandler.sendMessage(message);
                        }
                        break;
                }
            }
        }
    }

    /**
     * 是否正在扫描
     * @return
     */
    public static boolean isBleScaning(){
        return BluetoothAdapter.getDefaultAdapter().isDiscovering();
    }

    public boolean cancelScan(){
        boolean cancel = false;
        if(isBleScaning()){
            Log.e("BluetoothScan","cancelScan");
            try {
                cancel = BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return cancel;
    }

    public void scanBle(){
        if(null != onBleScanCallback){
            onBleScanCallback.onScanStarted();
        }
        bleList = null;
        if(!BluetoothAdapter.getDefaultAdapter().isEnabled()){
            boolean enable = false;
            try {
                //开启蓝牙
                enable = BluetoothAdapter.getDefaultAdapter().enable();
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("BluetoothScan",e.toString());
            }

            if(!enable){
                onScanFinished();
                return;
            }
        }
        try{
            cancelScan();
            Thread.sleep(500);
        }catch (Exception e){
            e.printStackTrace();
            Log.e("BluetoothScan",e.toString());
        }
        //使用新api扫描 注册广播
        registerScanBroadcast();
//        BluetoothAdapter.getDefaultAdapter().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY,10000);
        boolean success = BluetoothAdapter.getDefaultAdapter().startDiscovery();
        Log.e("BluetoothScan","startDiscovery="+success);
        //旧api扫描
//        boolean success = BluetoothAdapter.getDefaultAdapter().startLeScan(BluetoothAdapter.LeScanCallback);
        if(!success){
            //没权限会返回false
            onScanFinished();
        }else {
            scanHandler.sendEmptyMessageDelayed(H_DISCOVERY_TIME_OUT,6000);
        }
    }

    public void onScanFinished(){
        unregisterScanBroadcast();
//        if(null != onBleScanCallback){
//            onBleScanCallback.onScanFinished(bleList);
//        }
        scanHandler.sendEmptyMessage(H_DISCOVERY_FINISHED);
    }

    private OnBleScanCallback onBleScanCallback;

    public void setOnBleScanCallback(OnBleScanCallback onBleScanCallback) {
        this.onBleScanCallback = onBleScanCallback;
    }

    public interface OnBleScanCallback{
        void onScanStarted();
        void onScanning(BluetoothDevice bleDevice, int rssi);
        void onScanFinished(List<BleEntity> list);
    }

    private final class ScanHandler extends Handler {

        ScanHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            Log.e("BluetoothHandler","Message="+msg.toString());
            switch (msg.what) {
                case H_DISCOVERY_TIME_OUT:
                case H_DISCOVERY_FINISHED:{
                    if(null != onBleScanCallback){
                        Log.e("BluetoothHandler","bleList="+bleList);
                        onBleScanCallback.onScanFinished(bleList);
                    }
                    break;
                }
                case H_DISCOVERY_FOUND:{
                    if(null != onBleScanCallback){
                        onBleScanCallback.onScanning((BluetoothDevice)msg.obj,msg.arg1);
                    }
                    break;
                }
//                case H_DISCOVERY_TIME_OUT:{
//                    if(null != onBleScanCallback){
//                        onBleScanCallback.onScanFinished(bleList);
//                    }
//                    break;
//                }
            }
        }
    }
}
